bitkeeper revision 1.1041.2.2 (40e2ec02psfxj9RKCAgBaiEIUJeF7A)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 30 Jun 2004 16:36:18 +0000 (16:36 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 30 Jun 2004 16:36:18 +0000 (16:36 +0000)
Add explicit synchronous connect/disconnect methods to port objects
in xend.

tools/python/xen/lowlevel/xu/xu.c
tools/python/xen/xend/server/SrvDaemon.py
tools/python/xen/xend/server/channel.py

index ae11ce6885f2f4a253921f79cfc621359e47f020..55a5795209dc27441b2ba0d8090094d4f7aa76b9 100644 (file)
@@ -38,9 +38,6 @@
 #define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
 #define EVTCHN_DEV_MAJOR 10
 #define EVTCHN_DEV_MINOR 200
-#define PORT_NORMAL     0x0000   /* A standard event notification.      */ 
-#define PORT_EXCEPTION  0x8000   /* An exceptional notification.        */
-#define PORTIDX_MASK    0x7fff   /* Strip subtype to obtain port index. */
 /* /dev/xen/evtchn ioctls: */
 /* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
 #define EVTCHN_RESET  _IO('E', 1)
@@ -81,7 +78,7 @@ static PyObject *xu_notifier_read(PyObject *self, PyObject *args)
     }
     
     if ( bytes == sizeof(v) )
-        return Py_BuildValue("(i,i)", v&PORTIDX_MASK, v&~PORTIDX_MASK);
+        return PyInt_FromLong(v);
 
  none:
     Py_INCREF(Py_None);
@@ -145,7 +142,7 @@ static PyMethodDef xu_notifier_methods[] = {
     { "read",
       (PyCFunction)xu_notifier_read,
       METH_VARARGS,
-      "Read a (@port, @type) pair.\n" },
+      "Read a @port with pending notifications.\n" },
 
     { "unmask", 
       (PyCFunction)xu_notifier_unmask,
@@ -199,10 +196,6 @@ static PyObject *xu_notifier_new(PyObject *self, PyObject *args)
 
 static PyObject *xu_notifier_getattr(PyObject *obj, char *name)
 {
-    if ( strcmp(name, "EXCEPTION") == 0 )
-        return PyInt_FromLong(PORT_EXCEPTION);
-    if ( strcmp(name, "NORMAL") == 0 )
-        return PyInt_FromLong(PORT_NORMAL);
     return Py_FindMethod(xu_notifier_methods, obj, name);
 }
 
@@ -686,43 +679,6 @@ typedef struct xu_port_object {
 
 static PyObject *port_error;
 
-static int xup_connect(xu_port_object *xup, domid_t dom,
-                       int local_port, int remote_port){
-    // From our prespective rx = producer, tx = consumer.
-    int err = 0;
-    printf("%s> dom=%u %d:%d\n", __FUNCTION__, (unsigned int)dom, 
-           local_port, remote_port);
-
-    // Consumer = tx.
-    //xup->interface->tx_resp_prod = 0;
-    //xup->interface->tx_req_prod = 0;
-    xup->tx_resp_prod = xup->interface->tx_resp_prod;
-    xup->tx_req_cons = xup->interface->tx_resp_prod;
-    printf("%s> tx: %u %u : %u %u\n", __FUNCTION__,
-           (unsigned int)xup->interface->tx_resp_prod,
-           (unsigned int)xup->tx_resp_prod,
-           (unsigned int)xup->tx_req_cons,
-           (unsigned int)xup->interface->tx_req_prod);
-
-    // Producer = rx.
-    //xup->interface->rx_req_prod  = 0;
-    //xup->interface->rx_resp_prod = 0;
-    xup->rx_req_prod  = xup->interface->rx_req_prod;
-    xup->rx_resp_cons = xup->interface->rx_resp_prod;
-    printf("%s> rx: %u %u : %u %u\n", __FUNCTION__,
-           (unsigned int)xup->rx_resp_cons,
-           (unsigned int)xup->interface->rx_resp_prod,
-           (unsigned int)xup->interface->rx_req_prod,
-           (unsigned int)xup->rx_req_prod);
-
-    xup->remote_dom   = dom;
-    xup->local_port   = local_port;
-    xup->remote_port  = remote_port;
-
-    printf("%s< err=%d\n", __FUNCTION__, err);
-    return err;
-}
-
 static PyObject *xu_port_notify(PyObject *self, PyObject *args)
 {
     xu_port_object *xup = (xu_port_object *)self;
@@ -913,6 +869,86 @@ static PyObject *xu_port_space_to_write_response(
     return PyInt_FromLong(1);
 }
 
+static int __xu_port_connect(xu_port_object *xup)
+{
+    xc_dominfo_t info;
+
+    if ( xup->mem_fd != -1 )
+        return 0;
+
+    if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
+    {
+        PyErr_SetString(port_error, "Could not open '/dev/mem'");
+        return -1;
+    }
+
+    /* Set the General-Purpose Subject whose page frame will be mapped. */
+    (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)xup->remote_dom);
+
+    if ( (xc_domain_getinfo(xup->xc_handle, xup->remote_dom, 1, &info) != 1) ||
+         (info.domid != xup->remote_dom) )
+    {
+        PyErr_SetString(port_error, "Failed to obtain domain status");
+        (void)close(xup->mem_fd);
+        xup->mem_fd = -1;
+        return -1;
+    }
+
+    xup->interface = 
+        map_control_interface(xup->mem_fd, info.shared_info_frame);
+    if ( xup->interface == NULL )
+    {
+        PyErr_SetString(port_error, "Failed to map domain control interface");
+        (void)close(xup->mem_fd);
+        xup->mem_fd = -1;
+        return -1;
+    }
+
+    /* Synchronise ring indexes. */
+    xup->tx_resp_prod = xup->interface->tx_resp_prod;
+    xup->tx_req_cons  = xup->interface->tx_resp_prod;
+    xup->rx_req_prod  = xup->interface->rx_req_prod;
+    xup->rx_resp_cons = xup->interface->rx_resp_prod;
+
+    return 0;
+}
+
+static void __xu_port_disconnect(xu_port_object *xup)
+{
+    if ( xup->mem_fd == -1 )
+        return;
+    unmap_control_interface(xup->mem_fd, xup->interface);
+    (void)close(xup->mem_fd);
+    xup->mem_fd = -1;
+}
+
+static PyObject *xu_port_connect(PyObject *self, PyObject *args)
+{
+    xu_port_object *xup = (xu_port_object *)self;
+
+    if ( !PyArg_ParseTuple(args, "") )
+        return NULL;
+
+    if ( __xu_port_connect(xup) != 0 )
+        return NULL;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *xu_port_disconnect(PyObject *self, PyObject *args)
+{
+    xu_port_object *xup = (xu_port_object *)self;
+
+    if ( !PyArg_ParseTuple(args, "") )
+        return NULL;
+
+    __xu_port_disconnect(xup);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 static PyMethodDef xu_port_methods[] = {
     { "notify",
       (PyCFunction)xu_port_notify,
@@ -959,6 +995,16 @@ static PyMethodDef xu_port_methods[] = {
       METH_VARARGS,
       "Returns TRUE if there is space to write a response message.\n" },
 
+    { "connect",
+      (PyCFunction)xu_port_connect,
+      METH_VARARGS,
+      "Synchronously connect to remote domain.\n" },
+
+    { "disconnect",
+      (PyCFunction)xu_port_disconnect,
+      METH_VARARGS,
+      "Synchronously disconnect from remote domain.\n" },
+
     { NULL, NULL, 0, NULL }
 };
 
@@ -969,26 +1015,19 @@ static PyObject *xu_port_new(PyObject *self, PyObject *args)
     xu_port_object *xup;
     u32 dom;
     int port1, port2;
-    xc_dominfo_t info;
 
     if ( !PyArg_ParseTuple(args, "i", &dom) )
         return NULL;
 
     xup = PyObject_New(xu_port_object, &xu_port_type);
 
-    if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
-    {
-        PyErr_SetString(port_error, "Could not open '/dev/mem'");
-        goto fail1;
-    }
-
-    /* Set the General-Purpose Subject whose page frame will be mapped. */
-    (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)dom);
+    xup->remote_dom = dom;
+    xup->mem_fd     = -1; /* currently disconnected */
 
     if ( (xup->xc_handle = xc_interface_open()) == -1 )
     {
         PyErr_SetString(port_error, "Could not open Xen control interface");
-        goto fail2;
+        goto fail1;
     }
 
     if ( dom == 0 )
@@ -1002,7 +1041,7 @@ static PyObject *xu_port_new(PyObject *self, PyObject *args)
         if ( port1 < 0 )
         {
             PyErr_SetString(port_error, "Could not open channel to DOM0");
-            goto fail3;
+            goto fail2;
         }
     }
     else if ( xc_evtchn_bind_interdomain(xup->xc_handle, 
@@ -1010,34 +1049,22 @@ static PyObject *xu_port_new(PyObject *self, PyObject *args)
                                          &port1, &port2) != 0 )
     {
         PyErr_SetString(port_error, "Could not open channel to domain");
-        goto fail3;
+        goto fail2;
     }
 
-    if ( (xc_domain_getinfo(xup->xc_handle, dom, 1, &info) != 1) ||
-         (info.domid != dom) )
-    {
-        PyErr_SetString(port_error, "Failed to obtain domain status");
-        goto fail4;
-    }
+    xup->local_port  = port1;
+    xup->remote_port = port2;
 
-    xup->interface = 
-        map_control_interface(xup->mem_fd, info.shared_info_frame);
-    if ( xup->interface == NULL )
-    {
-        PyErr_SetString(port_error, "Failed to map domain control interface");
-        goto fail4;
-    }
+    if ( __xu_port_connect(xup) != 0 )
+        goto fail3;
 
-    xup_connect(xup, dom, port1, port2);
     return (PyObject *)xup;
-
     
- fail4:
-    (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
  fail3:
-    (void)xc_interface_close(xup->xc_handle);
+    if ( dom != 0 )
+        (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
  fail2:
-    (void)close(xup->mem_fd);
+    (void)xc_interface_close(xup->xc_handle);
  fail1:
     PyObject_Del((PyObject *)xup);
     return NULL;        
@@ -1058,11 +1085,10 @@ static PyObject *xu_port_getattr(PyObject *obj, char *name)
 static void xu_port_dealloc(PyObject *self)
 {
     xu_port_object *xup = (xu_port_object *)self;
-    unmap_control_interface(xup->mem_fd, xup->interface);
+    __xu_port_disconnect(xup);
     if ( xup->remote_dom != 0 )
         (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
     (void)xc_interface_close(xup->xc_handle);
-    (void)close(xup->mem_fd);
     PyObject_Del(self);
 }
 
index 31ace1b84ea1af9045305f4cf3625108cfd89b44..1f66ecc933520f0c0741c3af04820bd5f7218e2d 100644 (file)
@@ -169,13 +169,10 @@ class NotifierProtocol(protocol.Protocol):
     def __init__(self, channelFactory):
         self.channelFactory = channelFactory
 
-    def notificationReceived(self, idx, type):
-        #print 'NotifierProtocol>notificationReceived>', idx, type
+    def notificationReceived(self, idx):
         channel = self.channelFactory.getChannel(idx)
-        if not channel:
-            return
-        #print 'NotifierProtocol>notificationReceived> channel', channel
-        channel.notificationReceived(type)
+        if channel:
+            channel.notificationReceived()
 
     def connectionLost(self, reason=None):
         pass
@@ -251,9 +248,8 @@ class NotifierPort(abstract.FileDescriptor):
             notification = self.notifier.read()
             if not notification:
                 break
-            (idx, type) = notification
-            self.protocol.notificationReceived(idx, type)
-            self.notifier.unmask(idx)
+            self.protocol.notificationReceived(notification)
+            self.notifier.unmask(notification)
             count += 1
         #print 'NotifierPort>doRead<'
 
index d68f84fa37623d6697cd537de3687dcf38188aad..214020214b250de300d491129b009d57ceae85af 100755 (executable)
@@ -107,22 +107,14 @@ class BaseChannel:
         """
         return self.idx
 
-    def notificationReceived(self, type):
+    def notificationReceived(self):
         """Called when a notification is received.
         Closes the channel on error, otherwise calls
         handleNotification(type), which should be defined
         in a subclass.
         """
-        #print 'notificationReceived> type=', type, self
-        if self.closed: return
-        if type == self.factory.notifier.EXCEPTION:
-            print 'notificationReceived> EXCEPTION'
-            info = xc.evtchn_status(self.idx)
-            if info['status'] == 'unbound':
-                print 'notificationReceived> EXCEPTION closing...'
-                self.close()
-                return
-        self.handleNotification(type)
+        if not self.closed:
+            self.handleNotification(type)
 
     def close(self):
         """Close the channel. Calls channelClosed() on the factory.